import pygame
import sys
import math
from tools import *

pygame.init()
size = width, height = 620, 450
screen = pygame.display.set_mode(size)
pygame.display.set_caption("见缝插针")
fps = 60
fclock = pygame.time.Clock()
WHITE = 255, 255, 255
bg_color = 139, 134, 167
PURPLE = 114, 100, 122
ball_group = []
font = pygame.font.Font(r"C:\Windows\Fonts\simsun.ttc", 18)
stage_font = pygame.font.Font(r"C:\Windows\Fonts\simsun.ttc", 30)
# 转轴的中心位置
shaft = x0, y0 = 310, 160
# 针的长度
length = 140
# 转动的角速度
angular_speed = 0.004 * math.pi
stage = 8
# 每关要插的针的数量
ball_num = [10, 14, 12, 20, 13, 14, 16, 26]
remain_ball = 0
stage1 = [0, math.pi / 2, math.pi, math.pi * 1.5]
stage2 = [0, math.pi / 2, math.pi, math.pi * 1.5]
stage3 = [0, math.pi / 3, math.pi * 2 / 3, math.pi, math.pi * 4 / 3, math.pi * 5 / 3]
stage4 = [0, math.pi]
stage5 = [0, math.pi / 3, math.pi * 2 / 3, math.pi, math.pi * 4 / 3, math.pi * 5 / 3]
stage6 = [0, math.pi / 4, math.pi / 2, math.pi, math.pi * 3 / 4, math.pi, math.pi * 5 / 4, math.pi * 3 / 2,
          math.pi * 7 / 4]
stage7 = [0, math.pi / 4, math.pi / 2, math.pi, math.pi * 3 / 4, math.pi, math.pi * 5 / 4, math.pi * 3 / 2,
          math.pi * 7 / 4]
stage8 = [0, math.pi]
all_stage = [stage1, stage2, stage3, stage4, stage5, stage6, stage7, stage8]
gaming = True
stage_pass = False


class Ball:
    """
    针头
    """

    def __init__(self, angle):
        self.x = x0
        self.y = y0 + length
        self.center = (self.x, self.y)
        self.radius = 12
        self.angle = angle
        ball_group.append(self)

    def draw(self, surface):
        pygame.draw.line(surface, WHITE, shaft, self.center, 2)
        pygame.draw.circle(surface, WHITE, self.center, 12)

    def move(self, speed):
        """
        围绕转轴做圆周运动
        :param speed: 转动的角速度
        :return:
        """
        if self.angle < 2 * math.pi:
            self.angle += speed
        else:
            self.angle = self.angle - 2 * math.pi
        self.x = x0 - length * math.sin(self.angle)
        self.y = y0 + length * math.cos(self.angle)
        self.center = (self.x, self.y)


def check_collide(new_ball):
    for ball in ball_group:
        distance = math.sqrt(abs(ball.x - new_ball.x) ** 2 + abs(ball.y - new_ball.y) ** 2)
        if ball is not new_ball and distance <= new_ball.radius * 2:
            return True
    return False


def game_init():
    global stage, gaming, remain_ball, stage_pass

    if stage == len(all_stage):
        stage = 1
    elif stage_pass:
        stage += 1
    ball_group.clear()
    for a in all_stage[stage - 1]:
        b = Ball(a)
    remain_ball = ball_num[stage - 1]
    pygame.time.delay(200)
    gaming = True
    stage_pass = False


button = Button('重新开始', color=(220, 0, 0))
button.rect.center = shaft
button.click_connect(game_init)


def restart():
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        button.get_click(event)


def game_stage():
    global remain_ball, stage, gaming, stage_pass
    if remain_ball == 0 and gaming:
        stage_pass = True
        gaming = False


def update():
    screen.fill(bg_color)
    # 左上角关卡信息
    stage_num = stage_font.render('第{}关'.format(stage), True, WHITE)
    stage_rect = stage_num.get_rect()
    stage_rect.left = 5
    stage_rect.top = 5
    screen.blit(stage_num, stage_rect)
    # 绘制转轴的圆盘
    pygame.draw.circle(screen, WHITE, (310, 160), 42)
    # 绘制剩余针头提示
    pygame.draw.circle(screen, WHITE, (310, 380), 12)
    # 剩余针头数量
    remain_num = font.render('{}'.format(remain_ball), True, PURPLE)
    remain_rect = remain_num.get_rect()
    remain_rect.center = (310, 380)
    screen.blit(remain_num, remain_rect)
    for ball in ball_group:
        if gaming:
            ball.move(angular_speed)
        ball.draw(screen)
    if not gaming:
        if stage_pass and stage < len(all_stage):
            button.set_text('下一关')
        elif stage_pass and stage >= len(all_stage):
            button.set_text('重新开始')
        elif not stage_pass:
            button.set_text('重玩此关')
        button.draw(screen)


def main():
    global gaming, remain_ball, stage
    while True:
        if gaming:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                    if remain_ball > 0:
                        new_ball = Ball(0)
                        remain_ball -= 1
                        if check_collide(new_ball):
                            gaming = False
        else:
            restart()
        game_stage()
        update()
        pygame.display.update()
        fclock.tick(fps)


if __name__ == '__main__':
    game_init()
    main()
